#ifndef _GAME_CLASSES_H__
#define _GAME_CLASSES_H__

 #include "Ogre.h"
 #include "OIS\\OIS.h"
// #include "remSnd.h"
 using namespace Ogre;
 using namespace OIS;

enum DrawMenu {MENU=1,PAUSE=2,ABOUT=3,PLAY=4,OVER=5,PLAY2=7};
enum Bon {UPDATE,LIFE,BRON,FIRE,TIME,STABS,NUL};
enum Napram {DOWN=-2,LEFT=-1,UP=0,RIGHT=1};
enum TypeGame {ONE=1,TWO=2,FLAG=3,DEAD=4,POIN=5,NOGAME=6,EXIT=0,ELSE=-1};

const SIZE_BONUS = 6;
const TIME_PAUSE = 10;
const TIME_BRON = 10;
const TIME_POINT_ACTIVE = 10;
const MAX_FLAG = 5;
const TIME_UPDATE_BOTS = 5;
const TIME_CREATE_BOT = 3;
const TIME_CREATE_BOT_BOMB = 2; 
const ACTIVE_BOTS = 3;
const TIME_STAB = 10;
const TIME_CREATE = 2;
const float COLL_SIZE_MAP = 0.9275;
const float COLL_SIZE_BOMB = 0.311;
const float COLL_SIZE_TBOMB = 1.325;
const float COLL_SIZE_TANK = 1.9525;
const SIZE_MAP = 784;	//28x28

class Effect1
{
private:
	Entity *eEff[5];
	SceneNode *nEff[5];
	ParticleSystem *pEff[5];
	float minRadius,maxRadius;
	String MeshFile[5];
	int i;
	Vector3 V;
	Real step;
	Real cstep;
	float stepX[5],stepY[5];
	bool active[5],p;
	float SizeStep;
	Real angel;
public:
	void Initial(SceneManager *mScene,String Name);
	void setRadius(float minR,float maxR);
	bool Create(Vector3 &V);
	bool Update();
	void Dead();
	float func(int n);
};

class Effect2
{
private:
	BillboardSet *bSet;
	Billboard *bEff;
	SceneNode *nEff;
	String MaterialFile;
	int i,Num;
	int time_life;
	Real Time;
	bool active;
public:
	void Initial(SceneManager *mScene,String Name);
	bool Create(Vector3 &V,int n);
	bool Update();
	void Dead();
};

class Effect3
{
private:
	Entity *eEff[6];
	SceneNode *nEff[6];
	ParticleSystem *pEff;
	float minRadius,maxRadius;
	//String MeshFile[8];
	int i;
	Vector3 V;
	Real step;
	Real cstep;
	float stepX[6],stepY[6];
	bool active[6],p;
	float SizeStep;
	Real angel;
public:
	void Initial(SceneManager *mScene,String Name);
	void setRadius(float minR,float maxR);
	bool Create(Vector3 &V);
	bool Update();
	void Dead();
	float func(int n);
};

class Effect4
{
private:
	BillboardSet *bSet;
	Billboard *bEff;
	SceneNode *nEff;
	String MaterialFile;
	int i,Num;
	int time_life;
	Real Time;
	bool active;
public:
	void Initial(SceneManager *mScene,String Name);
	bool Create(Vector3 &V);
	bool Update();
	void Dead();
};


class Effects
{
private:
	Effect1 Eff1[5];
	Effect2 Eff2[5];
	Effect3 Eff3[5];
	Effect4 Eff4[5];
	int i;
public:
	void Initial(SceneManager *mScene);
	void AddEffect(int n,Vector3 &V,int s=0);
	void Update();
};

class Bonus
{
private:
	Entity *eBonus[SIZE_BONUS];
	Entity *eAlpha;
	SceneNode *nBonus;
	Real TNewBonus,TActiveBonus,TimeBonus;
	int i;
	Bon ActivBonus;
public:
	bool Active;
	void InBonus(SceneManager *SceneM);
	void Create(bool p);
	void Delete();
	inline void Update();
	void Fire();
	void setTNewBonus(Real R);
	void setTActiveBonus(Real R);
	Real getTNewBonus();
	Real getTActiveBonus();
	Bon getBonus();
	Vector3 getPosition();
};

class MyOverlay
{
private:
	Overlay *Fon;
    Overlay *Menu;
	Overlay *About;
	Overlay *Pause;
	Overlay *Play2;
	Overlay *Stats;
	Overlay *Over;
	char lastchange;
	char n;
	DrawMenu Draw;
	bool play;
public:
	void setShow(DrawMenu Dm);
	void InOverlay();
	void ChangeTo(int n);
	void setStatPlayer1(int score,int life);
	void setStatPlayer2(int score,int life);
	void setStatB(int BotD);
	void setStatCreate(int level,int CountBot);
	void OverPrint(String Caption);
	char getn();
	void Next();
	void Priov();
	TypeGame Enter();
	bool Esc(bool &Ex);
	DrawMenu getDraw();
};

class Map
{
private:
	char i,j;
	int cc;
	Entity *eMap,*Endr,*eG,*sEnd;
	SceneManager *SceneMgn;
	bool p,p1;
	StaticGeometry* sGeom;
	StaticGeometry* msGeom[SIZE_MAP];
	char *mapmas;
	inline	char& getElement(char &x,char &y){return mapmas[x*sx+y];};
	void CreateElement(char x,char y,char n);
	bool Shadow;
public:
	char sx;
	char tx1,ty1,tx2,ty2,ty,tx,tx3,ty3;
	//float Sx,Sy;
	Map();
	~Map();
	void Init(SceneManager *SceneM,bool Shadows=false);
	void LoadMap(const char *filename);
	void LoadMapB(const char *filename);
	void CreateMap(SceneManager *SceneM);
	inline bool Collision(Vector3 &V,int alpha,float Size);
	inline bool Boom(Vector3 &V,float Size,bool b=false);
	bool DeleteElement(char x,char y,bool b=false);
	void CreateStab(char n);
};

class Bomb
{
private:
	int x,y;
	float i;
	Vector3 V1,V2;
	Vector3 Move;
	Real mMove;
	SceneNode *nBomb;
public:
	Entity *eBomb;
	ParticleSystem *pSys;
	Bomb();
	~Bomb();
	void Init(SceneManager *SceneM,String name);
	void Create(Vector3 &V,float &alpha);
	inline Vector3 Update();
	void Fire();
	Vector3 getPosition();
	bool Collision(Bomb &b);
};

class Tank
{
private:
	int i;
	Vector3 tV;
	Vector3 V1,V2;
	Real TimeBron;
	bool Shadow;
public:
	Real Speed;
	Bomb mBomb;
	float alpha;
	int al,cBomb;
	SceneNode *nTank;
	Entity *eTank;
	Entity *eShadow;
	Entity *eBron;
	void Rotate(int angel);
	void Init(SceneManager *SceneM,String Name,String MaterialName,const char *filename,bool Shad=false);
	 void Create(Vector3 V);
	void setShadow(int tS=0);
	inline void Move();
	void CreateBomb();
	void Brone(bool b);
	void setSpeed(double speed);
	Vector3 NextMove();
	void Dead();
	Vector3 getPosition(SceneNode *node);
	Vector3 getPosition();
	void SetBomb(int n);
	bool Colise(const Tank &T);
	bool Colise(const Vector3 &V);
};


class Bots:public Tank
{
private:
	int i,r,tm;
	int pmas[ACTIVE_BOTS];
	SceneManager *mScene;
	bool p;
	Real Upd,UpdF;
public:
	char masbot[60];
	bool bactiv[ACTIVE_BOTS];
	Tank mBot[ACTIVE_BOTS];
	int CountBots,ActivBots,Value,DeadBots,up,cActive;
	void Rand(int E,int N,int X);
	bool InitBot(SceneManager *mScene,bool Shadow);
	bool InitBot2(SceneManager *mScene,bool Shadow);
	bool CreateBot();
	bool CreateBot2();
	int getmas(int n);
	void Add();
	void Delet();
	void Deads(int n);
	void Fire(int n);
	void setActiveBot(int n);
	void Update(int n);
	Vector3 getPosition(const int n);
};
class Poin
{
private:
	SceneNode *nPoin;
	Entity *ePoin;
	Entity *ePlan;
	char Activ;
public:
	Poin();
	void Initial(SceneManager *SceneM,String name);
	void Create(Vector3 &V);
	void setActive(char ch);
	char getActive();
	Vector3 getPosition();
};

class Flag
{
private:
	Vector3 Vstart;
	SceneNode *nFlag;
	SceneNode *nPlan;
	Entity *eFlag;
	Entity *ePlan;
public:
	void Initial(SceneManager *SceneM,String name);
	void Create(Vector3 &V);
	void setStart();
	void setPosition(Vector3 &V);
	void setStartPosition();
	Vector3 getPosition();
	Vector3 getStart();
};

class Player :public Tank
	{
	private:
		int money;
		int life,Level;
		Real TimeCreate;
		int Score;
		KeyCode kLeft,kRight,kUp,kDown,kFire;
	public:
		int i,keys;
		float ActiveBomb;
		bool keyFire,Super,Player2;
		Real Time_Point;
		int Count_Flag;
		bool ActivFlag;
//		bool Player;//false=Player1,true=Player2
		Player();
		~Player();
		void move();
		void UpdateFire();
		void dead();
		bool keyPressed(const KeyEvent &arg);
		bool keyReleased(const KeyEvent &arg);
		int getLife();
		int getScore();
		void AddLife();
		void setLife(int l);
		void AddScore(int n);
		void UpLevel();
		void setKeys(int Left,int Right,int Up,int Down,int Fire);
};

class Gamer
{
private:
	SceneManager *mScene;
	Map mMap;
	String ds;
	Vector3 tVect;
	int i,j,u,ran,p,i1,Level;
	Bon ActiveBonus;
	Real Btim1,BotPause1,Btim2,BotPause2;
	bool mExit,Play,Player2;
	Entity  *eStab;
	SceneNode *nStab;
	Camera *rCam;
	Effects mEff;
	Real Speed;
	Real stabt;
	bool stabcreate;
//	remSnd Snd3D;
	bool Shadow,bEff;
	Real timer,UpdPoin;
	char *MapName[4];
	char *MapNameD[4];
	MyOverlay mOverlayl;
	Flag Flag1,Flag2;
	Poin mPoin;
public:
	Gamer();
	~Gamer();
	Bots Bot1,Bot2;
	Bonus mBonus;
	Player mPlayer1,mPlayer2;
	Vector3 Col;
	void In(SceneManager *SceneM,Camera *Cam);
	void Create();
	void NextLevel();
	void LoadOptions(char *filename);
	void setBonus(Player &P);
	void frame(const Real &time);
	void UpdateBomb();
	void UpdateBombP(Player &Pl,Bots &B);
	void UpdateBombBot(Bots &B,Player &Pl);
	bool keyPressed(const KeyEvent &arg);
	bool keyReleased(const KeyEvent &arg);
	Vector3 getPosition(const SceneNode *nod);
	inline bool CollisionV(const Vector3 &V1,const Vector3 &V2,float size);
	void Colise(Player &P,Bots &B);
	void Colise(Bots &B,Player &P,bool Update=false);
	void GameOver(char ch=0);
	void CreatePlayer(Player &P);
};

#endif